package com.maimang.platform.shiro.service;

import com.maimang.platform.common.entity.SysUser;
import com.maimang.platform.common.service.SysUserService;
import com.maimang.platform.common.utils.MessageUtils;
import com.maimang.platform.constant.Constants;
import com.maimang.platform.exception.user.UserPasswordNotMatchException;
import com.maimang.platform.exception.user.UserPasswordRetryLimitExceedException;
import com.maimang.platform.manager.AsyncManager;
import com.maimang.platform.manager.factory.AsyncFactory;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 登录密码方法
 *
 * @author Rocky
 */
@Component
public class SysPasswordService {
	@Autowired
	private CacheManager cacheManager;

	private Cache<String, AtomicInteger> loginRecordCache;

	@Value(value = "${user.password.maxRetryCount}")
	private String maxRetryCount;

	@PostConstruct
	public void init() {
		loginRecordCache = cacheManager.getCache("loginRecordCache");
	}

	public void validate(SysUser user, String password) {
		String loginName = user.getLoginName();

		AtomicInteger retryCount = loginRecordCache.get(loginName);

		if (retryCount == null) {
			retryCount = new AtomicInteger(0);
			loginRecordCache.put(loginName, retryCount);
		}
		if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue()) {
			AsyncManager.me().execute(AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount)));
			throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue());
		}

		if (!matches(user, password)) {
			AsyncManager.me().execute(AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count", retryCount)));
			loginRecordCache.put(loginName, retryCount);
			throw new UserPasswordNotMatchException();
		} else {
			clearLoginRecordCache(loginName);
		}
	}

	public void validateUserid(SysUser user, String userid) {
		String loginName = user.getLoginName();

		AtomicInteger retryCount = loginRecordCache.get(loginName);

		if (retryCount == null) {
			retryCount = new AtomicInteger(0);
			loginRecordCache.put(loginName, retryCount);
		}
		if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue()) {
			AsyncManager.me().execute(AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount)));
			throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue());
		}

		if (!matchUserid(user, userid)) {
			AsyncManager.me().execute(AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count", retryCount)));
			loginRecordCache.put(loginName, retryCount);
			throw new UserPasswordNotMatchException();
		} else {
			clearLoginRecordCache(loginName);
		}
	}

	public boolean matchUserid(SysUser user, String userid) {
		return user.getUserid().equals(userid);
	}
	public boolean matches(SysUser user, String newPassword) {
		return user.getPassword().equals(encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
	}

	public void clearLoginRecordCache(String username) {
		loginRecordCache.remove(username);
	}

	public String encryptPassword(String username, String password, String salt) {
		return new Md5Hash(username + password + salt).toHex();
	}

	public static void main(String[] args) {
		// System.out.println(new SysPasswordService().encryptPassword("admin", "123456", "111111"));
		// System.out.println(new SysPasswordService().encryptPassword("Rocky", "123456", "222222"));
		// System.out.println(new SysPasswordService().encryptPassword("platform", "123456", "333333"));
		// System.out.println(new SysPasswordService().encryptPassword("赵锦涛", "123456", "dbfb79"));
		System.out.println(new SysPasswordService().encryptPassword("admin", "123456", "aad5a5"));
		System.out.println(new Md5Hash("admin123456aad5a5").toHex());
	}
}
